package com.zzzfwd.menuhelper

import androidx.lifecycle.ViewModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlin.random.Random

class MenuViewModel(private val menuRepository: MenuRepository) : ViewModel() {

    companion object {
        private const val MAX_ITERATIONS = 1000
    }

    fun validateTotalPrice(configurations: List<Configuration>, totalPrice: Int): ValidationResult {
        var minPrice = 0
        var maxPrice = 0
        for (configuration in configurations) {
            if (configuration.selected) {
                val dish = configuration.dish
                minPrice += dish.price * dish.minWeight
                maxPrice += dish.price * dish.maxWeight
            }
        }

        return if (totalPrice in minPrice..maxPrice) {
            ValidationResult(true, minPrice, maxPrice)
        } else {
            ValidationResult(false, minPrice, maxPrice)
        }
    }

    fun generateResult(): String {
        val selectedDishes = getSelectedDishes()

        val targetPrice = getTotalPrice()
        var totalPrice = 0
        var iterations = 0

        while (totalPrice != targetPrice && iterations < MAX_ITERATIONS) {
            totalPrice = 0

            for (selectedDish in selectedDishes) {
                selectedDish.weight = 0
            }

            for (selectedDish in selectedDishes) {
                val dish = selectedDish.dish
                val weight = getRandomWeight(dish.minWeight, dish.maxWeight)
                totalPrice += dish.price * weight
                selectedDish.weight = weight
            }

            iterations++
        }

        val result = buildString {
            appendLine("已选择的菜:")
            for (selectedDish in selectedDishes) {
                appendLine(
                    "${selectedDish.dish.name}: " +
                            "[ 单价: ${selectedDish.dish.price}, " +
                            "数量: ${selectedDish.weight}, " +
                            "金额: ${selectedDish.totalPrice} ]"
                )
            }
            appendLine("总价: $totalPrice")
            appendLine("迭代次数: $iterations")
            if (iterations == MAX_ITERATIONS) {
                appendLine("达到最大迭代次数，没有找到合适的结果")
            }
        }
        return result
    }

    fun getSelectedDishes() =
        getConfigurations().asSequence()
            .filter { it.selected }
            .map { SelectedDish(it.dish, 0) }
            .toList()

    fun getTotalPrice() = menuRepository.getTotalPrice()

    fun saveTotalPrice(totalPrice: Int) = menuRepository.saveTotalPrice(totalPrice)

    fun getConfigurations() =
        menuRepository.getConfigurations()?.let {
            Gson().fromJson(it, object : TypeToken<List<Configuration>>() {})
        } ?: emptyList()

    fun saveConfigurations(configurations: List<Configuration>) =
        menuRepository.saveConfigurations(Gson().toJson(configurations))

    private fun getRandomWeight(minWeight: Int, maxWeight: Int) =
        Random.nextInt(minWeight, maxWeight + 1)
}